#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#define MAX 256
char **buffer;
sem_t empty; //定义同步信号量 empty
sem_t full;  //定义同步信号量 full
sem_t mutex; //定义互斥信号量 mutex
int check[10] = {0};    //缓冲区状态
void *producer() //生产者
{
    // 10个缓冲区
    buffer = (char **)malloc(10 * sizeof(char *));
    for (int i = 0; i < 10; i++)
    {
        buffer[i] = (char *)malloc(MAX);
    }
    
    while (1)
    {
        sem_wait(&empty); // empty 的 P 操作
        sem_wait(&mutex); // mutex 的 P 操作
        printf("input something to buffer:");
        // buffer = (char *)malloc(MAX); //给缓冲区分配内存空间
        for (int i = 0; i < 10; i++)
        {
            if (check[i] == 0)
            {
                fgets(buffer[i], MAX, stdin); //输入产品至缓冲区
                check[i] = 1;
                break;
            }
        }
        sem_post(&mutex); // mutex 的 V 操作
        sem_post(&full);  // full 的 V 操作
    }
}
void *consumer() //消费者
{
    while (1)
    {
        sem_wait(&full);  // full 的 P 操作
        sem_wait(&mutex); // mutex 的 P 操作
        for (int i = 0; i < 10; i++)
        {
            if (check[i] == 1)
            {
                printf("read product from buffer:%s", buffer[i]); //从缓冲区中取出产品
                memset(buffer[i], 0, MAX);                        //清空缓冲区
                check[i] = 0;
                break;
            }
        }
        sem_post(&mutex); // mutex 的 V 操作
        sem_post(&empty); // empty 的 V 操作
    }
}
int main()
{
    pthread_t id_producer;
    pthread_t id_consumer;
    int ret;
    sem_init(&empty, 0, 10);                                  //设置 empty 到初值为 10
    sem_init(&full, 0, 0);                                    //设置 full 到初值为 0
    sem_init(&mutex, 0, 1);                                   //设置 mutex 到初值为 1
    ret = pthread_create(&id_producer, NULL, producer, NULL); //创建生产者线程
    ret = pthread_create(&id_consumer, NULL, consumer, NULL); //创建消费者线程
    pthread_join(id_producer, NULL);                          //等待生产者线程结束
    pthread_join(id_consumer, NULL);                          //等待消费者线程结束
    sem_destroy(&empty);                                      //删除信号量
    sem_destroy(&full);
    sem_destroy(&mutex);
    printf("The End...\n");
}